package com.gtt.jr.util;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;

import org.apache.commons.io.FileUtils;

/**
 * 文件处理工具
 * 
 * @author 高甜甜(gao12581@sina.com)
 * @date 2010-9-11
 * 
 */
public class ImageUtils {

	private static final String SLASH = "/";
	private static final String COMMA = ".";
	private static final String RESOURCE = "resource";
	private static final String THUMB = "_th";
	private static final String SLIDE = "_sl";
	private static final int MAX_THUMB_WIDTH = 200;
	private static final int MAX_THUMB_HEIGHT = 200;
	private static final int MAX_SLIDE_WIDTH = 600;
	private static final int MAX_SLIDE_HEIGHT = 600;

	/**
	 * 保存图片
	 * 
	 * @param file
	 * @param suffix
	 * @param basePath
	 * @return
	 * @throws IOException
	 */
	public static Map<String, String> savePicture(File file, String suffix,
			String basePath) throws IOException {
		Map<String, String> result = new HashMap<String, String>();
		String uuid = makeUUID();
		String filename = generateFilename(suffix, uuid, ImageType.ORIGINAL);
		String slidename = generateFilename(suffix, uuid, ImageType.SLIDE);
		String thumbname = generateFilename(suffix, uuid, ImageType.THUMB);
		File newFile = new File(basePath + filename);
		FileUtils.copyFile(file, newFile);

		File thumbFile = new File(basePath + thumbname);
		generateThumb(newFile, thumbFile, MAX_THUMB_WIDTH, MAX_THUMB_HEIGHT,
				false);

		File slideFile = new File(basePath + slidename);
		generateThumb(newFile, slideFile, MAX_SLIDE_WIDTH, MAX_SLIDE_HEIGHT,
				true);

		// addWaterMark(newFile, suffix);

		result.put("url", filename);
		result.put("surl", slidename);
		result.put("turl", thumbname);

		return result;
	}

	// private static void addWaterMark(File newFile, String suffix)
	// throws IOException {
	// BufferedImage image = ImageIO.read(newFile);
	// BufferedImage markImage = addWaterMark(image, image.getWidth(),
	// image.getHeight());
	// ImageIO.write(markImage, suffix, newFile);
	// }

	public static void main(String[] args) throws IOException {
		File file = new File("D:\\test\\test.jpg");
		String suffix = "jpg";
		String basePath = "D:\\test";
		savePicture(file, suffix, basePath);
	}

	/**
	 * 生成指定大小限制的缩略图
	 * 
	 * @param srcFile
	 * @param thumbFile
	 * @throws IOException
	 */
	private static void generateThumb(File srcFile, File thumbFile,
			int targetWidth, int targetHeight, boolean watermark)
			throws IOException {
		BufferedImage image = ImageIO.read(srcFile);
		int oldWidth = image.getWidth();
		int oldHeight = image.getHeight();
		int newWidth = oldWidth;
		int newHeight = oldHeight;

		double widthRate = targetWidth * 1.0 / oldWidth;
		double heightRate = targetHeight * 1.0 / oldHeight;
		if (widthRate < heightRate && widthRate < 1) {
			newWidth = targetWidth;
			newHeight = oldHeight * targetWidth / oldWidth;
		} else if (heightRate < 1) {
			newWidth = oldWidth * targetHeight / oldHeight;
			newHeight = targetHeight;
		}

		BufferedImage thumb = getScaledInstance(image, newWidth, newHeight,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);

		if (watermark)
			thumb = addWaterMark(thumb, newWidth, newHeight);

		ImageIO.write(thumb, "jpg", thumbFile);
	}

	private static BufferedImage addWaterMark(BufferedImage img, int width,
			int height) throws IOException {
		int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB
				: BufferedImage.TYPE_INT_ARGB;
		BufferedImage tmp = new BufferedImage(width, height, type);
		Graphics2D g2 = tmp.createGraphics();
		g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g2.drawImage(img, 0, 0, width, height, null);

		Image mark = ImageIO.read(ImageUtils.class
				.getResourceAsStream("watermark.png"));
		g2.drawImage(mark, width - 150, height - 25, 139, 20, null);
		g2.dispose();
		return tmp;
	}

	/**
	 * 缩放图片
	 * 
	 * @param img
	 * @param targetWidth
	 * @param targetHeight
	 * @param hint
	 * @param higherQuality
	 * @return
	 */
	private static BufferedImage getScaledInstance(BufferedImage img,
			int targetWidth, int targetHeight, Object hint,
			boolean higherQuality) {
		int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB
				: BufferedImage.TYPE_INT_ARGB;
		BufferedImage ret = (BufferedImage) img;
		int w, h;
		if (higherQuality) {
			w = img.getWidth();
			h = img.getHeight();
		} else {
			w = targetWidth;
			h = targetHeight;
		}

		do {
			if (higherQuality && w > targetWidth) {
				w /= 2;
				if (w < targetWidth) {
					w = targetWidth;
				}
			}

			if (higherQuality && h > targetHeight) {
				h /= 2;
				if (h < targetHeight) {
					h = targetHeight;
				}
			}

			BufferedImage tmp = new BufferedImage(w, h, type);
			Graphics2D g2 = tmp.createGraphics();
			g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
			g2.drawImage(ret, 0, 0, w, h, null);
			g2.dispose();

			ret = tmp;
		} while (w != targetWidth || h != targetHeight);

		return ret;
	}

	/**
	 * 生成文件名
	 * 
	 * @param suffix
	 * @param uuid
	 * @param type
	 * @return
	 */
	private static String generateFilename(String suffix, String uuid,
			ImageType type) {
		String prefix = "";
		switch (type) {
		case THUMB:
			prefix = THUMB;
			break;
		case SLIDE:
			prefix = SLIDE;
			break;
		default:
			break;
		}

		return SLASH + RESOURCE + SLASH + String.valueOf(uuid.charAt(0))
				+ SLASH + uuid + prefix + COMMA + suffix;
	}

	private static String makeUUID() {
		return UUID.randomUUID().toString();
	}

}
